﻿using AForge.Video.DirectShow;
using EDesk.kit;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace EDesk.apis.camera
{
    public partial class CameraForm : Form
    {

        private FilterInfoCollection devs;
        private VideoCaptureDevice videoSource;
        private static int devIndex = -1;

        private bool saveDisk;
        private String picFilePath;
        private String picFileName;
        private String picFileExt;

        public CameraResult result;

        public bool SaveDisk { get => saveDisk; set => saveDisk = value; }
        public string PicFilePath { get => picFilePath; set => picFilePath = value; }
        public string PicFileName { get => picFileName; set => picFileName = value; }
        public string PicFileExt { get => picFileExt; set => picFileExt = value.ToLower(); }

        public CameraForm()
        {
            InitializeComponent();
        }

        private void CameraForm_Load(object sender, EventArgs e)
        {
            initDevList();
            initPlayer();
        }

        private void initDevList()
        {
            try
            {
                devs = new FilterInfoCollection(FilterCategory.VideoInputDevice);
                if (devs.Count > 0)
                {
                    devList.Items.Clear();
                    foreach (FilterInfo device in devs)
                    {
                        devList.Items.Add(device.Name);
                    }
                    if(devIndex == -1) devIndex = 0;
                    devList.SelectedIndex = devIndex;
                }
            }
            catch (ApplicationException)
            {
                devList.Items.Add("未找到摄像头设备");
                devs = null;
            }
        }

        private void devList_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (devs == null) return;
            devIndex = devList.SelectedIndex;
            videoSource = null;
            close_player();
            initPlayer();
        }

        private void initPlayer()
        {
            if (devs == null) return;
            if(videoSource == null)
            {
                videoSource = new VideoCaptureDevice(devs[devIndex].MonikerString);
            }
            player.VideoSource = videoSource;
            player.Start();
        }

        private void close_player()
        {
            if (player.IsRunning)
            {
                player.SignalToStop();
                player.WaitForStop();
            }
            button1.Enabled = false;
        }

        private void CameraForm_Deactivate(object sender, EventArgs e)
        {
            close_player();
        }

        private void CameraForm_Activated(object sender, EventArgs e)
        {
            initPlayer();
        }

        private void Btn_frame(object sender, EventArgs e)
        {
            Bitmap bitMap = player.GetCurrentVideoFrame();
            picBox.Image = bitMap;
            picBox.SizeMode = PictureBoxSizeMode.StretchImage;
            button2.Enabled = true;
        }

        private void Btn_ok(object sender, EventArgs e)
        {
            Bitmap bitmap = (Bitmap)picBox.Image;
            String base64 = ImgBase64.ImgToBase64(bitmap);
            string path = null;

            if (saveDisk)
            {
                DirectoryInfo dir = new DirectoryInfo(picFilePath);
                dir.Create();
                path = $"{picFilePath}\\{picFileName}.{picFileExt}";
                bitmap.Save(path, getImgFormat(picFileExt));
            }

            result = new CameraResult()
            {
                picBase64 = base64,
                picFile = path
            };
            close_player();
            this.DialogResult = DialogResult.OK;
            this.Close();
        }

        private void player_NewFrame(object sender, ref Bitmap image)
        {
            button1.Enabled = true;
        }

        private ImageFormat getImgFormat(string ext)
        {
            if(ext == "png")
            {
                return ImageFormat.Png;
            }
            else if (ext == "bmp")
            {
                return ImageFormat.Bmp;
            }
            else if (ext == "gif")
            {
                return ImageFormat.Gif;
            }
            return ImageFormat.Jpeg;
        }

    }
}
